home *** CD-ROM | disk | FTP | other *** search
- # include "ctlmod.h"
- # include "pipes.h"
- # include <resp.h>
- # include <sccs.h>
-
- SCCSID(@(#)do_seq.c 8.1 12/31/84)
-
- /*
- ** DO_SEQ -- do sequence of states
- **
- ** The sequence of states indicated by the start state
- ** ppb->pb_st is executed.
- **
- ** Recursion and multiple processes are implemented in
- ** this routine. For each iteration through the top
- ** loop, the next state to call is checked. If the state
- ** is local (in this process), the state is executed and
- ** the next state is computed. If the state is remote,
- ** (contained in another process), we write out the
- ** current call on a pipe which will (eventually) get
- ** to the target process. In this case (and the system
- ** reset case) the next state is unknown. This causes
- ** this routine to read the input pipe for a command.
- ** The command read is then executed -- notice that it
- ** does not matter if this command is part of this level
- ** of call (a sibling of the 'call'd process) or a lower
- ** level (a descendent), since 'call' saved the state.
- **
- ** If there are no more states in the chain after execution
- ** of a local state, then a response block is generated.
- ** The 'readinput' call can also generate one of these.
- ** If the return is local (to this process), it is just
- ** returned. Otherwise, it sends it off to the process
- ** currently blocked for this state sequence to complete,
- ** and the PB_UNKNOWN state is reentered.
- **
- ** Parameters:
- ** ppb -- a pointer to the pipe block which
- ** (a) describes the state to call and
- ** (b) provides an I/O area.
- **
- ** Returns:
- ** none
- **
- ** Side Effects:
- ** Lots. The side effects of all the states.
- ** Leaves 'Resp' set to the response of the last
- ** state in the chain.
- **
- ** Called By:
- ** call
- ** main
- **
- ** Trace Flags:
- ** 2.0 - 2.7
- */
-
- do_seq(ppb)
- register pb_t *ppb;
- {
- register int i;
-
- /*
- ** Top Loop.
- ** Iterate until we have a response block intended
- ** for this process (and hence this state, since
- ** state invocations are properly nested inside
- ** process invocations).
- ** We also insure that we can always get at the
- ** current pipe block.
- **
- ** We return from the setjmp with non-zero value if
- ** we get a fatal error.
- */
-
- Ctx.ctx_ppb = ppb;
- if (setjmp(Ctx.ctx_jbuf) != 0)
- return;
-
- for (;;)
- {
- # ifdef xCTR1
- if (tTf(2, 0))
- lprintf("do_seq: state %d\n", ppb->pb_st);
- # endif
- /* take cases */
- switch (ppb->pb_st)
- {
- case PB_UNKNOWN:
- /*
- ** Read the input and get a state, since we
- ** don't have one already. This will set
- ** Parmc & Parmv and change *ppb. The
- ** state it found will be processed next
- ** time through the loop.
- */
-
- readinput(ppb);
- break;
-
- case PB_NONE:
- /*
- ** The 'no next state' case, i.e., a response.
- ** This only happens if the response is
- ** for this process, so we just return.
- */
-
- # ifdef xCTR1
- if (tTf(2, 1))
- lprintf("do_seq: exit\n");
- # endif
- return;
-
- default:
- /*
- ** The state is known, let do_st do all
- ** the dirty work. Hand it the global
- ** Parmc & Parmv to pass to the function.
- ** Do_st returns the next state to execute.
- */
-
- ppb->pb_st = i = do_st(ppb, Ctx.ctx_pc, Ctx.ctx_pv);
- if (i == PB_NONE)
- {
- # ifdef xCM_DEBUG
- if (ppb->pb_resp == PB_UNKNOWN)
- syserr("do_seq: pb_resp");
- # endif
- ppb->pb_proc = ppb->pb_resp;
- if (ppb->pb_proc != Cm.cm_myproc)
- {
- /* write to correct process */
- pb_prime(ppb, PB_RESP);
- send_off(ppb, 0, (PARM *)NULL);
- pb_flush(ppb);
-
- /* next state is unknown */
- ppb->pb_st = PB_UNKNOWN;
- }
- }
- break;
- }
- }
- }
-